﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2013-11-17
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once

struct FIPMAC
{
    ACHAR name[64];                 // 网卡名
    BYTE ipadr[4];                  // IP地址
    BYTE mac[6];                    // MAC地址
    BYTE reserve[16];               // 保留参数
};

struct FHTTP_PARAMETER
{
    size_t start_postion;           // 支持断点续传时的开始下载字节位置
     const ACHAR* castr;            // HTTPS时的证书信息，空或者0表示非HTTPS

    FHTTP_PARAMETER()
        :start_postion(0)
        ,castr(0)
    {}
};

class IFNetClient : public IFMemObject
{
protected:
    explicit IFNetClient(){}

public:
    // 设置线程的打印名
    virtual void SetThreadName(const ACHAR* name) = 0;
    // 初始化连接功能
    virtual bool Initialize() = 0;
    // 启动连接器，并自动创建多线程并行连接
    // 此函数是非阻塞模式，返回结果不是连接是否成功
    // .host,port 主机URL和端口，IP也行
    // .connect_time_out 连接超时设置（单位秒），0表示无限等待
    // .return 返回值只是连接线程和连接参数是否正确，线程是否启动成功，连接状态是否成功请访问状态
    virtual EF_NET_CONNECT_RESULT TryConnect(const ACHAR* host, INT port, LONG connect_time_out) = 0;
    // 主动断开连接
    virtual void Disconnect() = 0;
    // 连接状态
    virtual EF_NET_SOCKET_STATE GetStatus() = 0;
    // 发送数据
    // .return 失败返回0，成功返回发送了多少字节，通常情况下与入参size相同
    virtual size_t SendBuf(void* p, size_t size) = 0;
    // 接收数据，要循环接收（最大64K）
    virtual bool RecvBuf(FV_BYTE& out) = 0;
    // 断开连接
    virtual void Destroy(){ Disconnect(); }
    // 是否是刚刚连接上（在连接状态为OK里可查询，查询一次后失效）
    virtual bool IsNewConnected() = 0;
    // 获取当前连接信息（在已经连接的情况下才可用，通过连接127.0.0.1建立的服务器获取将失败）
    virtual bool GetIpMac(FIPMAC& out) = 0;
};


// 获建一个简单TCP/IP客户端
extern FAPI IFNetClient* FNewNetClient(FNEW_FUNC_API);


// 获取HTTP/HTTPS目标（文件下载时阻塞模式，建议多线程处理）
// .url 目标主机URL
// .ret 如果请求成功，则存储了返回的结果串（UTF8格式）
// .connect_time_out 连接超时设置，单位秒
// .ca HTTPS模式下的证书，如果填0表示非HTTPS
extern FAPI EF_HTTP_REQ_RESULT FHttpGet(const ACHAR* url, FV_ACHAR& ret, LONG connect_time_out = 15, const ACHAR* ca = 0);

// 数据到达函数
// .data 从网络到达的数据首地址
// .size,count 到达的数据长度及数量
// .dst 由FHttpDownload传入的自定义数据地址
// .return 返回写入了多少字节，或者全部：return size * count;
typedef size_t (*FHttpDownloadFunc)(void* data, size_t size, size_t count, void* dst);
// 下载进度处理函数
// .dst 由FHttpDownload传入的自定义数据地址
//      由FHttpPost传入wd的容器地址
// ,total 总长度（down_为下载处理，up_为上传处理）
// .now 当前处理长度（down_为下载处理，up_为上传处理）
typedef int (*FHttpProgressFunc)(void* dst, double down_total, double down_now, double up_total, double up_now);
// 获取HTTP/HTTPS目标，但自定义内容保存
// .url 下载地址
// .func 数据到达接收函数
// .progress 数据进度函数，可以填0（down_total，down_now有效）
// .dst 用户数据地址，下载器不修改，并传递到回调函数
extern FAPI EF_HTTP_REQ_RESULT FHttpDownload(const ACHAR* url, FHttpDownloadFunc func, FHttpProgressFunc progress, void* dst, LONG connect_time_out = 15, FHTTP_PARAMETER* pvl = 0);

// 上传数据到HTTP/HTTPS
// .url 目标主机URL
// .wd 要写入的数据
// .ret 如果请求成功，则存储了返回的结果串（UTF8格式）
// .progress 数据进度函数，可以填0（up_total，up_now有效）
// .connect_time_out 连接超时设置，单位秒
// .ca HTTPS模式下的证书，如果填0表示非HTTPS
extern FAPI EF_HTTP_REQ_RESULT FHttpPost(const ACHAR* url, FV_BYTE& wd, FV_ACHAR& ret, FHttpProgressFunc progress, LONG connect_time_out = 15, const ACHAR* ca = 0);

struct FMAILINFOW
{
    FStringW loginName;      // 登录邮箱帐号
    FStringW loginPwd;       // 登录邮箱密码
    FStringW szSender;       // 发送者邮箱地址
    FStringW szSenderName;   // 发送者名称
    FStringW szReceiver;     // 接收者邮箱地址
    FStringW szReceiverName; // 接收者名称
    FStringW szTitle;        // 邮件标题
    FStringW szText;         // 邮件正文
    FVStringW vAttachment;   // 附件文件列表
};
struct FMAILINFOA
{
    FStringA loginName;      // 登录邮箱帐号
    FStringA loginPwd;       // 登录邮箱密码
    FStringA szSender;       // 发送者邮箱地址
    FStringA szSenderName;   // 发送者名称
    FStringA szReceiver;     // 接收者邮箱地址
    FStringA szReceiverName; // 接收者名称
    FStringA szTitle;        // 邮件标题
    FStringA szText;         // 邮件正文
    FVStringA vAttachment;   // 附件文件列表
};
// 登陆smtp服务器自动发邮件（注意，单个附件文件最大为4M）
// .addr smtp服务器地址
// .is_ip_addr 指定参数addr是一个IP地址串还是一个域名串
extern FAPI bool FMailSendW(FMAILINFOW& mi, const WCHAR* addr, bool is_ip_addr);
extern FAPI bool FMailSendA(FMAILINFOA& mi, const ACHAR* addr, bool is_ip_addr);

// 获取本本的IP地址与MAC
// 只能获取未禁用的WINDOWS网卡或者无线网卡设备
// 安卓开了WIFI后才可能获取WIFI的IP和MAC
// .return 返回查询到几个记录
typedef FVector< FIPMAC > FV_IPMAC;
extern FAPI size_t FGetIpMac(FV_IPMAC& out);


#ifdef UNICODE
#define FMAILINFO                   FMAILINFOW
#define FMailSend                   FMailSendW
#else
#define FMAILINFO                   FMAILINFOA
#define FMailSend                   FMailSendA
#endif

#if FUEL_OS_WINDOWS
#define FFMAILINFO                  FMAILINFOW
#define FFMailSend                  FMailSendW
#else
#define FFMAILINFO                  FMAILINFOA
#define FFMailSend                  FMailSendA
#endif